//
//  ObservableViewController.swift
//  Example
//
//  Created by T AO on 2022/2/9.
//

import UIKit
import RxSwift

class ObservableViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

//        empty()
//        just()
        of()
//        from()
//        deferred()
//        range()
//        generate()
//        timer()
//        interval()
//        repeatElement()
//        error()
//        never()
//        create()
    }

}

// MARK: - 序列的创建方式

extension ObservableViewController {
    /// 空序列创建
    private func empty() {
        let emptyOb = Observable<Int>.empty()
        _ = emptyOb.subscribe(onNext: { num in
            print("订阅: \(num)")
        }, onError: { error in
            print("error: \(error)")
        }, onCompleted: {
            print("完成回调")
        }, onDisposed: {
            print("释放回调")
        })
    }
    
    /// just 创建序列
    private func just() {
        let array = ["111", "222"]
        
        _ = Observable<[String]>.just(array)
            .subscribe(onNext: { value in
                print("订阅: \(value)")
            }, onError: { error in
                print("error: \(error)")
            }, onCompleted: {
                print("完成回调")
            }, onDisposed: {
                print("释放回调")
            })
    }
    
    /// of: 创建新的可观察序列
    /// 多个元素：针对序列处理
    private func of() {
        // String
        Observable<String>.of("aaa", "bbb")
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
        
        // 字典
        Observable<[String: Any]>.of(["name": "T AO", "age": 29])
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
        
        // 数组
        Observable<[String]>.of(["aaa", "bbb", "ccc"])
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
    }
    
    /// from: 可选序列 --> 可观察序列
    private func from() {
        // 数组
        Observable<[String]>.from(optional: ["a", "b"])
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
        
        /// 字典
        Observable<[String: Any]>.from(optional: ["name": "T AO", "age": 29])
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
        
        /// set
        Observable<Set>.from(optional: [1, 2, 3, 1, 2])
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
    }
    
    /// deferred: 延迟序列初始化
    private func deferred() {
        var isOdd = true
        _ = Observable<Int>.deferred({
            isOdd = !isOdd
            if isOdd {
                return Observable.of(1, 3, 5, 7, 9)
            } else {
                return Observable.of(2, 4, 6, 8, 10)
            }
        })
        .subscribe({ event in
            print("event: \(event)")
        })
    }
    
    /// range: 使用指定的调度程序生成生成指定范围内的可观察整数序列
    private func range() {
        Observable.range(start: 2, count: 5)
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: DisposeBag())
    }
    
    /// generate: 给定条件循环运行，生成序列
    private func generate() {
        Observable.generate(initialState: 0,        // 初始值
                            condition: { $0 < 10 }, // 条件 1
                            iterate: { $0 + 2 })    // 条件 2
            .subscribe { event in
                print(event)
            }
            .disposed(by: DisposeBag())
        
        // 数组遍历
        let array = ["a", "b", "c", "d", "e"]
        Observable.generate(initialState: 0,
                            condition: { $0 < array.count },
                            iterate: { $0 + 1 })
            .subscribe(onNext: {
                print(array[$0])
            })
            .disposed(by: DisposeBag())
    }
    
    /// timer: 在指定的初始相对到期时间过后定期生成一个值
    private func timer() {
        Observable<Int>.timer(RxTimeInterval.milliseconds(5000),
                              period: RxTimeInterval.seconds(2),
                              scheduler: MainScheduler.instance)
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: disposeBag)
        
        // 因为没有指定期限period,故认定为一次性
        Observable<Int>.timer(RxTimeInterval.seconds(1), scheduler: MainScheduler.instance)
            .subscribe { event in
                print("++++ \(event)")
            }
            .disposed(by: disposeBag)
    }
    
    /// interval: 定时生成序列，发送响应
    private func interval() {
        Observable<Int>.interval(RxTimeInterval.seconds(3),
                                 scheduler: MainScheduler.instance)
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: disposeBag)
    }
    
    /// repeatElement: 生成无限重复给定元素可观察序列
    private func repeatElement() {
        Observable<Int>.repeatElement(5)
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: disposeBag)
    }
    
    /// error：生成一个以 error 结束的序列
    private func error() {
        Observable<String>.error(NSError(domain: "请求错误", code: 10086, userInfo: ["reason": "unknown"]))
            .subscribe { event in
                print("evnet: \(event)")
            }
            .disposed(by: disposeBag)
    }
    
    /// never: 生成一个永远不会发出 event，也不会结束的序列
    private func never() {
        Observable<String>.never()
            .subscribe { event in
                print("event: \(event)")
            }
            .disposed(by: disposeBag)
    }
    
    private func create() {
        let observable = Observable<String>.create { observer in
            // 对订阅者发出了.next事件，且携带了一个数据"www.baidu.com"
            observer.onNext("www.baidu.com")
            // 对订阅者发出了.completed事件
            observer.onCompleted()
            // 因为一个订阅行为会有一个Disposable类型的返回值，所以在结尾一定要returen一个Disposable
            return Disposables.create()
        }
        
        // 订阅
        observable.subscribe {
            print("event: \($0)")
        }.disposed(by: disposeBag)
    }
}
